from flask import Blueprint, request, jsonify
from flask_jwt_extended import jwt_required, get_jwt_identity
from models import Category, Product, db
from utils import error, success
from datetime import datetime

category_api = Blueprint('category_api', __name__, url_prefix='/api/categories')

@category_api.route('/', methods=['GET'])
@jwt_required()
def get_categories():
    """获取分类列表"""
    try:
        page = request.args.get('page', 1, type=int)
        page_size = request.args.get('page_size', 10, type=int)
        name = request.args.get('name', '')
        parent_id = request.args.get('parent_id', type=int)
        
        query = Category.query
        
        # 搜索过滤
        if name:
            query = query.filter(Category.name.contains(name))
        if parent_id is not None:
            query = query.filter(Category.parent_id == parent_id)
        
        # 按创建时间倒序排列
        query = query.order_by(Category.created_at.desc())
        
        # 分页
        pagination = query.paginate(
            page=page, per_page=page_size, error_out=False
        )
        
        categories = []
        for category in pagination.items:
            # 获取父分类名称
            parent_name = None
            if category.parent_id:
                parent = Category.query.get(category.parent_id)
                parent_name = parent.name if parent else None
            
            categories.append({
                'id': category.id,
                'name': category.name,
                'description': category.description,
                'parent_id': category.parent_id,
                'parent_name': parent_name,
                'created_at': category.created_at.isoformat(),
                'updated_at': category.updated_at.isoformat()
            })
        
        return success(data={
            'categories': categories,
            'pagination': {
                'page': pagination.page,
                'page_size': pagination.per_page,
                'total': pagination.total
            }
        }).to_response()
        
    except Exception as e:
        return error(code=500, msg=f'获取分类列表失败: {str(e)}').to_response()

@category_api.route('/tree', methods=['GET'])
@jwt_required()
def get_category_tree():
    """获取分类树"""
    try:
        def build_tree(parent_id=None):
            categories = Category.query.filter_by(parent_id=parent_id).all()
            tree = []
            for category in categories:
                children = build_tree(category.id)
                tree.append({
                    'id': category.id,
                    'name': category.name,
                    'description': category.description,
                    'parent_id': category.parent_id,
                    'children': children,
                    'created_at': category.created_at.isoformat(),
                    'updated_at': category.updated_at.isoformat()
                })
            return tree
        
        tree = build_tree()
        
        return success(data=tree).to_response()
        
    except Exception as e:
        return error(code=500, msg=f'获取分类树失败: {str(e)}').to_response()


@category_api.route('/', methods=['POST'])
@jwt_required()
def create_category():
    """创建分类"""
    try:
        data = request.get_json()
        current_user_id = get_jwt_identity()
        
        # 检查当前用户是否为管理员
        from models import User
        current_user = User.query.get(current_user_id)
        if current_user.role != 'admin':
            return error(code=403, msg='权限不足').to_response()
        
        # 验证必填字段
        if not data.get('name'):
            return error(code=400, msg='分类名称不能为空').to_response()
        
        # 检查分类名称是否已存在（同级分类下）
        parent_id = data.get('parent_id')
        existing_category = Category.query.filter_by(
            name=data['name'], 
            parent_id=parent_id
        ).first()
        if existing_category:
            return error(code=400, msg='同级分类下已存在相同名称的分类').to_response()
        
        # 如果指定了父分类，检查父分类是否存在
        if parent_id:
            parent_category = Category.query.get(parent_id)
            if not parent_category:
                return error(code=400, msg='父分类不存在').to_response()
        
        # 创建分类
        category = Category(
            name=data['name'],
            description=data.get('description', ''),
            parent_id=parent_id
        )
        
        db.session.add(category)
        db.session.commit()
        
        return success(data={
            'id': category.id,
            'name': category.name,
            'parent_id': category.parent_id
        }, msg='分类创建成功').to_response()
        
    except Exception as e:
        db.session.rollback()
        return error(code=500, msg=f'创建分类失败: {str(e)}').to_response()

@category_api.route('/<int:category_id>', methods=['PUT'])
@jwt_required()
def update_category(category_id):
    """更新分类"""
    try:
        data = request.get_json()
        current_user_id = get_jwt_identity()
        
        # 检查当前用户是否为管理员
        from models import User
        current_user = User.query.get(current_user_id)
        if current_user.role != 'admin':
            return error(code=403, msg='权限不足').to_response()
        
        category = Category.query.get_or_404(category_id)
        
        # 更新字段
        if 'name' in data:
            # 检查分类名称是否已存在（同级分类下）
            parent_id = data.get('parent_id', category.parent_id)
            existing_category = Category.query.filter(
                Category.name == data['name'],
                Category.parent_id == parent_id,
                Category.id != category_id
            ).first()
            if existing_category:
                return error(code=400, msg='Category with same name already exists at same level').to_response()
            category.name = data['name']
        
        if 'description' in data:
            category.description = data['description']
        
        if 'parent_id' in data:
            new_parent_id = data['parent_id']
            # 检查父分类是否存在
            if new_parent_id:
                parent_category = Category.query.get(new_parent_id)
                if not parent_category:
                    return error(code=400, msg='Parent category does not exist').to_response()
                # 检查是否会形成循环引用
                if new_parent_id == category_id:
                    return error(code=400, msg='Cannot set self as parent category').to_response()
                # 检查是否会形成循环引用（递归检查）
                if _would_create_cycle(category_id, new_parent_id):
                    return error(code=400, msg='Cannot set category as its own child').to_response()
            category.parent_id = new_parent_id
        
        category.updated_at = datetime.utcnow()
        
        db.session.commit()
        
        return success(msg='分类更新成功').to_response()
        
    except Exception as e:
        db.session.rollback()
        return error(code=500, msg=f'Failed to update category: {str(e)}').to_response()

@category_api.route('/<int:category_id>', methods=['DELETE'])
@jwt_required()
def delete_category(category_id):
    """删除分类"""
    try:
        current_user_id = get_jwt_identity()
        
        # 检查当前用户是否为管理员
        from models import User
        current_user = User.query.get(current_user_id)
        if current_user.role != 'admin':
            return error(code=403, msg='权限不足').to_response()
        
        category = Category.query.get_or_404(category_id)
        
        # 检查是否有子分类
        children = Category.query.filter_by(parent_id=category_id).count()
        if children > 0:
            return error(code=400, msg='无法删除有子分类的分类').to_response()
        
        # 检查是否有商品使用该分类
        products = Product.query.filter_by(category_id=category_id).count()
        if products > 0:
            return error(code=400, msg='无法删除有关联商品的分类').to_response()
        
        db.session.delete(category)
        db.session.commit()
        
        return success(msg='分类删除成功').to_response()
        
    except Exception as e:
        db.session.rollback()
        return error(code=500, msg=f'Failed to delete category: {str(e)}').to_response()

def _would_create_cycle(category_id, new_parent_id):
    """检查是否会形成循环引用"""
    current_parent = new_parent_id
    while current_parent:
        if current_parent == category_id:
            return True
        parent = Category.query.get(current_parent)
        if not parent:
            break
        current_parent = parent.parent_id
    return False
